import torch

# 计算y=(x+w)*(w+1),y对w的导数
w = torch.tensor([1.], requires_grad=True)
x = torch.tensor([2.], requires_grad=True)

# print("w:{}\nx:{}".format(w,x))

a = torch.add(w, x)
# 用来保留非叶子结点的梯度
a.retain_grad()
b = torch.add(w, 1)
y = torch.mul(a, b)
# b.retain_grad()
# y.retain_grad()

# print("{}\n{}\n{}".format(a, b, y))

y.backward()
print(w.grad)

# 查看是否为叶子结点
print("is_leaf:", w.is_leaf, x.is_leaf, a.is_leaf, b.is_leaf, y.is_leaf)

# 查看梯度
# 在反向传播执行完毕后，非叶子结点的梯度会被释放，
# 在backward()执行前，使用retain_grad()方法可以保留非叶子结点的梯度
print("gradient:", w.grad, x.grad, a.grad, b.grad, y.grad)

# 查看grad_fn，查看结点是怎么得到的
# 非叶子结点才有这个属性
print("grad_fn:", w.grad_fn, x.grad_fn, a.grad_fn, b.grad_fn, y.grad_fn)
